package com.chenliang.check.base;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @program: myes
 * @description: 处理统一结果返回-- 返回值解析器
 * @author: 陈英俊
 * @create: 2021-09-09 14:22
 */
public class ResponseBodyHandler extends WebMvcConfigurationSupport implements HandlerMethodReturnValueHandler {
    public ResponseBodyHandler() {
    }

    public boolean supportsReturnType(MethodParameter methodParameter) {
        //return !methodParameter.getMethod().getDeclaringClass().isAnnotationPresent(BobCustomOutPut.class) && methodParameter.getMethod().getDeclaringClass().isAnnotationPresent(RestController.class) && !ObjectUtils.allNotNull(new Object[]{methodParameter.getMethod().getDeclaredAnnotation(BobCustomOutPut.class)});
        return true;
       // return methodParameter.getMethod().getDeclaringClass().isAnnotationPresent(RestController.class);
    }

    public void handleReturnValue(Object o, MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest) throws Exception {
        modelAndViewContainer.setRequestHandled(true);
        RespData<Object> resp = new RespData();
        resp.setResult(true, "-1", "success", o);
        HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);
        response.setContentType("application/json;charset=UTF-8");
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(this.createSimpleModule());
        mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString("");
            }
        });
        response.getWriter().append(this.writeFormatAsString(mapper, resp)).flush();
    }

    private String writeFormatAsString(ObjectMapper mapper, RespData<Object> resp) throws JsonProcessingException {
        String responseFormat = ApplicationPropertiesUtil.getProperty("bob.response.format", "true");
        return "true".equals(responseFormat) ? mapper.writerWithDefaultPrettyPrinter().writeValueAsString(resp) : mapper.writeValueAsString(resp);
    }

    protected Module createSimpleModule() {
        String typeFormat = ApplicationPropertiesUtil.getProperty("bob.response.typeFormat", "-1");
        SimpleModule simpleModule = new SimpleModule();
        if ("0".equals(typeFormat)) {
            simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
            simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        }

        return simpleModule;
    }
}
